home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
UTIL
/
MEMORY
/
OLD
/
MEM208SRC
/
!Memphis
/
c
/
spr
< prev
next >
Wrap
Text File
|
1993-09-08
|
5KB
|
187 lines
/*
* spr.c
* Part of the !Memphis distribution
* (c) bdb/nas, 1991-3
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "kernel.h"
#include "swis.h"
#include "_swis.h"
#include "sprite.h"
#include "interface.h"
#include "core.h"
#include "spr.h"
static int pagesize = 0x8000;
static int deadsize = 0;
static sprite_area *ss;
static int sssize;
static int ssfreeoff;
static int desired = 0;
static SPRITENAME deadname={ "mfsxdeadspr" }; /* Dead sprites names get 1st 4 chars set to this. */
#define DEADMARK (*(int *)&deadname)
static void readarea(void)
{
_swix(OS_ReadDynamicArea,_IN(0)|_OUT(0)|_OUT(1),3,&ss,&sssize);
ssfreeoff = sssize?ss->freeoff:sizeof(sprite_area);
_swix(OS_ReadMemMapInfo,_OUT(0),&pagesize);
}
/*{{{ */ static _kernel_oserror *growsprites( int grow ) /* ensure extra bytes in sprite area, 0=ok*/
{ _kernel_oserror *err;
readarea();
grow -= sssize - ssfreeoff;
if ( grow <= 0 )
return 0;
err = _swix(OS_ChangeDynamicArea,_IN(0)|_IN(1),3,-(-grow & ~(pagesize-1)));
readarea();
if (err)
printf("**************Failed to grow sprite area by %d bytes********",-(-grow & ~(pagesize-1)));
return err;
}
/*}}} */
/*{{{ */ static _kernel_oserror *shrinksprites( void ) /* Shrink sprite area if possible/desirable*/
{ int shrink;
_kernel_oserror *err;
readarea();
desired = ( _kernel_osbyte( 161, 147, 0 ) >> 8 & 0xFF ) * pagesize;
shrink = sssize - ssfreeoff - desired;
shrink = -(-shrink&~(pagesize-1));
if ( shrink <= 0 )
return NULL;
err=_swix( OS_ChangeDynamicArea, _IN(0)|_IN(1),3,-shrink);
readarea();
return err;
}
/*}}} */
/*{{{ */ static void deletedeadsprites( void )/**/
{ sprite_header *h,*ch;
int hsize;
readarea();
if (sssize)
{ for ( ch = h = ( sprite_header * )( ( char * )ss + ss->sproff );
h < ( sprite_header * )( ( char * )ss + ssfreeoff );
h = ( sprite_header * )( ( char * )h + hsize ) )
{ hsize = h->next;
if ( ( ( int * )&h->name )[0] != DEADMARK )
{ if (h != ch)
memmove(ch, h, hsize);
ch = (sprite_header *)((char *)ch + hsize);
}
else
ss->number--;
}
ssfreeoff = ss->freeoff = (char *)ch - (char *)ss;
}
deadsize = 0;
}
/*}}} */
/*{{{ */ sprite_header *findsprite( SPRITENAME name ) /* find sprite or NULL*/
{ sprite_header *h;
readarea();
if (sssize)
for ( h = ( sprite_header * )( ( char * )ss + ss->sproff );
h < ( sprite_header * )( ( char * )ss + ssfreeoff );
h = ( sprite_header * )( ( char * )h + h->next ) )
if ( ( ( int * )&name )[0]==( ( int * )&h->name )[0] &&
( ( int * )&name )[1]==( ( int * )&h->name )[1] &&
( ( int * )&name )[2]==( ( int * )&h->name )[2] )
return h;
return NULL;
}
/*}}} */
/*{{{ */ _kernel_oserror *createsprite( SPRITENAME name, int size, sprite_header **rh ) /* create sprite */
{ sprite_header *h;
_kernel_oserror *err;
size = ( size+3 )&~3;
if (deadsize > 0)
deletedeadsprites();
err=growsprites( SHSIZE + size );
if (err) return err;
h = ( sprite_header * )( ( char * )ss + ssfreeoff );
h->next = SHSIZE + size;
*( SPRITENAME * )&h->name = name;
h->width = 0;
h->height = size/4 - 1;
h->lbit = 0;
h->rbit = 31;
h->image = SHSIZE;
h->mask = SHSIZE;
h->mode = 18;
ss->freeoff += h->next;
ss->number++;
*rh = h;
return NULL;
}
/*}}} */
/*{{{ */ _kernel_oserror *setspritesize( sprite_header *h, int size ) /* set size */
{ _kernel_oserror *err;
int oldsize;
#ifdef DEBUG
printf( "setspritesize %p %x\n", h, size );
#endif
if ( !h )
return NULL;
oldsize = h->next-SHSIZE;
size = ( size+3 )&~3;
if ( size>oldsize )
{ err = growsprites( size-oldsize );
if (err) return err;
memmove( ( char * )h + SHSIZE + size,
( char * )h + h->next,
( char * )ss + ssfreeoff - ( ( char * )h + h->next ) );
ss->freeoff += size-oldsize;
h->height = size/4 - 1;
h->next = SHSIZE + size;
}
else
if ( size + SHSIZE+4 <= oldsize ) /* Room to truncate */
{ h->height = size/4 - 1;
h->next = SHSIZE + size;
h = (sprite_header *)((char *)h+h->next);
size = oldsize - size - SHSIZE;
h->next = SHSIZE + size;
*( SPRITENAME * )&h->name = deadname;
h->width = 0;
h->height = size/4 - 1;
h->lbit = 0;
h->rbit = 31;
h->image = SHSIZE;
h->mask = SHSIZE;
h->mode = 18;
deletesprite(h);
}
return NULL;
}
/*}}} */
/*{{{ */ _kernel_oserror *deletesprite( sprite_header *h ) /* mark as dead and maybe deletedead*/
{ if ( !h )
return NULL;
( ( int * )&h->name )[0] = DEADMARK;
deadsize += h->next;
if ( sssize - ssfreeoff + deadsize >= pagesize )
{ deletedeadsprites();
return shrinksprites();
}
return NULL;
}
/*}}} */
_kernel_oserror *spritefreespace( struct freespace *b)
{
readarea();
if (deadsize)
deletedeadsprites();
if (sssize)
{ b->free = ss->size - ss->freeoff;
b->biggest = b->free;
b->size = ss->size;
}
else
b->free = b->biggest = b->size = 0;
return NULL;
}